#include <qlib/utils/cellUtils.h>

namespace qlib {

CellElements::CellElements() {}
CellElements::CellElements(qlib::Cell::s_ptr cell) {
  CellElements(cell->reg);
}

CellElements::CellElements(entt::registry& reg) {
  {
    auto view = reg.view<qlib::Path::s_ptr>();
    view.each([&](entt::entity e, qlib::Path::s_ptr ptr) { paths.push_back({e, ptr}); });
  }

  {
    auto view = reg.view<qlib::Polygon::s_ptr>();
    view.each([&](entt::entity e, qlib::Polygon::s_ptr ptr) { polygons.push_back({e, ptr}); });
  }

  {
    auto view = reg.view<qlib::Rectangle::s_ptr>();
    view.each([&](entt::entity e, qlib::Rectangle::s_ptr ptr) { rectangles.push_back({e, ptr}); });
  }

  {
    auto view = reg.view<qlib::Label::s_ptr>();
    view.each([&](entt::entity e, qlib::Label::s_ptr ptr) { labels.push_back({e, ptr}); });
  }

  {
    auto view = reg.view<qlib::Text::s_ptr>();
    view.each([&](entt::entity e, qlib::Text::s_ptr ptr) { texts.push_back({e, ptr}); });
  }

  {
    auto view = reg.view<qlib::Ellipse::s_ptr>();
    view.each([&](entt::entity e, qlib::Ellipse::s_ptr ptr) { ellipses.push_back({e, ptr}); });
  }

  {
    auto view = reg.view<qlib::Fan::s_ptr>();
    view.each([&](entt::entity e, qlib::Fan::s_ptr ptr) { fans.push_back({e, ptr}); });
  }

  {
    auto view = reg.view<qlib::Ruler::s_ptr>();
    view.each([&](entt::entity e, qlib::Ruler::s_ptr ptr) { rulers.push_back({e, ptr}); });
  }

  {
    auto view = reg.view<qlib::Reference::s_ptr>();
    view.each([&](entt::entity e, qlib::Reference::s_ptr ptr) { references.push_back({e, ptr}); });
  }
}

template <typename T, typename... Args>
bool entity_valid_impl(entt::registry& reg, entt::entity e) {
  auto ptr = reg.try_get<std::shared_ptr<T>>(e);

  if (ptr != nullptr && *ptr != nullptr) {
    return true;
  }

  if constexpr (sizeof...(Args) > 0) {
    return entity_valid_impl<Args...>(reg, e);
  } else {
    return false;
  }
}

bool entity_valid(entt::registry& reg, entt::entity e) {
  return entity_valid_impl<QLIB_CELL_ELEMENT_TYPE>(reg, e);
}

}  // namespace qlib